package server.stackMachine;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.Socket;

import server.stackMachine.IntegerStackMachine.StackOverflowException;

public class IntegerStackMachineControler {

	final private IntegerStackMachine stackMachine = new IntegerStackMachine();
	final private Socket socket;
	final private BufferedReader reader;
	final private PrintWriter writer;

	public IntegerStackMachineControler(final Socket s, final BufferedReader br, final PrintWriter pw) {
		this.socket = s;
		this.reader = br;
		this.writer = pw;
	}

	public void control() throws IOException {
		while(!this.socket.isClosed()) {
			String s = this.reader.readLine();
			try {
				int i = Integer.parseInt(s);
				this.stackMachine.push(i);
			} catch (NumberFormatException e) {
				s = s.toLowerCase();
				try {
					Method m = this.stackMachine.getClass().getDeclaredMethod(s);
					Object ret = m.invoke(this.stackMachine);
					if (ret != null) {
						writer.println(ret.toString());
						writer.flush();
					}
				} catch (NoSuchMethodException e1) {
					if (s.compareTo("exit") == 0) break;
					writer.println("unknown command");
					writer.flush();
				} catch (SecurityException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				} catch (IllegalAccessException e2) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IllegalArgumentException e3) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (InvocationTargetException e4) {
					Throwable t = e.getCause();
					writer.println(t.getClass().getName());
					writer.println("aborting");
					writer.flush();
					break;
				}
			} catch (StackOverflowException e) {
				this.writer.println("StackOverflow, exiting");
				break;
			}
		}
	}

}
